package com.assistant.markdown;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Table
 *
 * @author yingjianhua
 */
public class Table<T> implements Content {

    private final List<T> data;
    private final Class<T> clazz;

    public Table(Class<T> clazz, List<T> data) {
        this.clazz = clazz;
        this.data = data;
    }

    @Override
    public String toString() {
        Field[] fields = clazz.getDeclaredFields();
        int maxIndex = Arrays.stream(fields).map(field -> {
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            if (excelProperty == null) {
                throw new RuntimeException(clazz.getSimpleName() + "的" + field.getName() + "字段请打上ExcelProperty注解！");
            }
            return excelProperty.index();
        }).max(Comparator.naturalOrder()).orElse(0);

        Map<Integer, Field> indexMap = Arrays.stream(fields).collect(Collectors.toMap(field -> {
            ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
            return excelProperty.index();
        }, field -> field));

        List<ExcelProperty> excelPropertyList = new ArrayList<>();
        List<Field> fieldList = new ArrayList<>();

        for (int i = 0; i < maxIndex + 1; i++) {
            Field field = indexMap.get(i);
            if (field == null) {
                excelPropertyList.add(null);
                fieldList.add(null);
            } else {
                excelPropertyList.add(field.getAnnotation(ExcelProperty.class));
                field.setAccessible(true);
                fieldList.add(field);
            }
        }

        StringBuilder stringBuilder = new StringBuilder();
        appendHead(stringBuilder, excelPropertyList);
        appendSplit(stringBuilder, excelPropertyList);
        for (T item : data) {
            if (item != null) {
                appendRow(stringBuilder, fieldList, item);
            }
        }
        return stringBuilder.toString();
    }

    private void appendRow(StringBuilder stringBuilder, List<Field> fieldList, T data) {
        stringBuilder.append("|");
        int index = 0;
        for (Field field : fieldList) {
            if (index != 0) {
                stringBuilder.append("|");
            }
            try {
                Object value = null;
                if (field != null) {
                    value = field.get(data);
                }
                stringBuilder.append((value == null || value.toString().length() == 0) ? " " : value.toString());
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new RuntimeException("这是什么问题？");
            }
            index++;
        }
        stringBuilder.append("|\n");
    }

    private void appendHead(StringBuilder stringBuilder, List<ExcelProperty> excelPropertyList) {
        stringBuilder.append("|");
        int index = 0;
        for (ExcelProperty excelProperty : excelPropertyList) {
            if (index != 0) {
                stringBuilder.append("|");
            }
            stringBuilder.append(excelProperty != null ? excelProperty.value()[0] : " ");
            index++;
        }
        stringBuilder.append("|\n");
    }

    private void appendSplit(StringBuilder stringBuilder, List<ExcelProperty> excelPropertyList) {
        stringBuilder.append("|");
        int index = 0;
        for (int i = 0; i < excelPropertyList.size(); i++) {
            if (index != 0) {
                stringBuilder.append("|");
            }
            stringBuilder.append("-----");
            index++;
        }
        stringBuilder.append("|\n");
    }
}
